/**
 * Description:     程序的主要部分。
 * Function:        详情见README.md
 * Contributor:     叶月枫, cZanY714285
 */

#define version "v1.3-alpha"

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>

#include "bmp.h"        // bmp文件处理
#include "imgG.h"       // 灰度转化
#include "imgH.h"       // 直方图均衡
#include "imgS.h"       // 平滑化

int main(int argc, char *argv[])
{
    // 命令合法性检测
    if (argc < 2)
    {
        printf("Wrong Command.\n");
        exit(EXIT_FAILURE);
    }

    if (strcmp(argv[1], "-v") == 0) // 判断版本号
    {
        printf("Version: %s\n", version);
        exit(EXIT_SUCCESS);
    }
    else if (strcmp(argv[1], "-g") == 0) // 判断 灰度增强
    {
        // 命令检测合法性
        if (argc != 7)
        {
            printf("Wrong Command.\n");
            exit(EXIT_FAILURE);
        }

        int a = atoi(argv[3]); // 参数读入
        int b = atoi(argv[4]);
        char fileIn[1000], fileOut[1000]; // 文件名读入
        if (strcpy(fileIn, argv[5]) == NULL || strcpy(fileOut, argv[6]) == NULL)
        {
            printf("Fail to read the filename.\n");
            exit(EXIT_FAILURE);
        }

        // 文件合法性
        if (getValidity(fileIn) == 0)
        {
            printf("The file format is wrong.\n");
            exit(EXIT_FAILURE);
        }
        else if (getValidity(fileIn) == -1)
        {
            printf("Fail to open file.\n");
            exit(EXIT_FAILURE);
        }

        // 灰度信息读入
        GARYSCALEBIT temp = getGrayscale(fileIn);

        // 进行线性灰度增强
        if (strcmp(argv[2], "-l") == 0)
        {
            linearEnhancement(&temp, a, b);
        }

        // 进行指数灰度增强
        else if (strcmp(argv[2], "-e") == 0)
        {
            exponentialEnhancement(&temp, a, b);
        }
        else
        {
            // 命令合法性
            printf("Wrong command.\n");
            exit(EXIT_FAILURE);
        }

        // 写入文件
        if (bmpWrite(temp.garyscale, fileIn, fileOut) != 0)
        {
            printf("Fail to Write in File.");
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("Success.\n");
        }

        // 释放指针
        free(getGrayscale(fileIn).garyscale);
    }
    else if (strcmp(argv[1], "-h") == 0) // 判断 直方图均衡化
    {
        // 命令检测合法性
        if (argc != 4)
        {
            printf("Wrong Command.\n");
            exit(EXIT_FAILURE);
        }

        // 文件名读入
        char fileIn[1000], fileOut[1000]; 
        if (strcpy(fileIn, argv[2]) == NULL || strcpy(fileOut, argv[3]) == NULL)
        {
            printf("Fail to read the filename.\n");
            exit(EXIT_FAILURE);
        }

        // 文件合法性
        if (getValidity(fileIn) == 0)
        {
            printf("The file format is wrong.\n");
            exit(EXIT_FAILURE);
        }
        else if (getValidity(fileIn) == -1)
        {
            printf("Fail to open file.\n");
            exit(EXIT_FAILURE);
        }

        // 灰度信息读入
        GARYSCALEBIT temp = getGrayscale(fileIn);

        // 进行直方图均衡化的处理
        if (imgH(temp) != 0)
        {
            printf("Fail to process.");
            exit(EXIT_FAILURE);
        }
        
        // 写入文件
        if (bmpWrite(temp.garyscale, fileIn, fileOut) != 0)
        {
            printf("Fail to Write in File.");
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("Success.\n");
        }

        // 释放指针
        free(getGrayscale(fileIn).garyscale);
    }
    else if (strcmp(argv[1], "-s") == 0) // 判断 平滑化
    {
        // 命令检测合法性
        if (argc != 5)
        {
            printf("Wrong Command.\n");
            exit(EXIT_FAILURE);
        }

        // 文件名读入
        char fileIn[1000], fileOut[1000]; 
        if (strcpy(fileIn, argv[2]) == NULL || strcpy(fileOut, argv[4]) == NULL)
        {
            printf("Fail to read the filename.\n");
            exit(EXIT_FAILURE);
        }

        // 文件合法性
        if (getValidity(fileIn) == 0)
        {
            printf("The file format is wrong.\n");
            exit(EXIT_FAILURE);
        }
        else if (getValidity(fileIn) == -1)
        {
            printf("Fail to open file.\n");
            exit(EXIT_FAILURE);
        }

        // 灰度信息读入
        GARYSCALEBIT temp = getGrayscale(fileIn);

        if (strcmp(argv[3], "-3") == 0) // 3*3平滑化
        {
            if (meanFilter_3(temp, fileIn) != 0)
            {
                printf("Fail to process.");
                exit(EXIT_FAILURE);
            }
        }
        else if (strcmp(argv[3], "-5") == 0) // 5*5平滑化
        {
            if (meanFilter_5(temp, fileIn) != 0)
            {
                printf("Fail to process.");
                exit(EXIT_FAILURE);
            }
        }
        else
        {
            printf("Wrong Command.\n");
            exit(EXIT_FAILURE);
        }
        
        // 写入文件
        if (bmpWrite(temp.garyscale, fileIn, fileOut) != 0)
        {
            printf("Fail to Write in File.");
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("Success.\n");
        }

        // 释放指针
        free(getGrayscale(fileIn).garyscale);
    }
    else // 错误命令
    {
        printf("Wrong command.\n");
        exit(EXIT_FAILURE);
    }

    return 0;
}